package gat.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import gat.RedisService;
import gat.common.enums.NoEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author sxq
 * @date 2021/12/14
 */

@Slf4j
@Service
public class RedisServiceImpl implements RedisService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    public String getSeq(String key, String digit) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmm");
        key = key + sf.format(System.currentTimeMillis());
        Long curSeq = incr(key, 1);
        long ttl = ttl(key);
        if (ttl == -1) {
            //设置过期 时间为1小时
            expire(key, 60 * 60);
        }
        return String.format(digit, curSeq);
    }

    public String getNewSeq(String key, String digit) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
        key = key + sf.format(System.currentTimeMillis());
        Long curSeq = incr(key, 1);
        long ttl = ttl(key);
        if (ttl == -1) {
            //设置过期 时间为1小时
            expire(key, 60 * 60);
        }
        return String.format(digit, curSeq);
    }

    @Override
    public String getNo(NoEnum noEnum) {
        String seq = getSeq(noEnum.getKey(), noEnum.getDigit());
        String time = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_FORMAT);
        return noEnum.getPrefix() + time + seq;
    }

    @Override
    public String getNewNo(NoEnum noEnum) {
        String seq = getNewSeq(noEnum.getKey(), noEnum.getDigit());
        String time = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_FORMAT);
        return noEnum.getPrefix() + time + seq;
    }


    /**
     * 实现命令：TTL key，以秒为单位，返回给定 key的剩余生存时间(TTL, time to live)。
     *
     * @param key
     * @return
     */
    @Override
    public long ttl(String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * 实现命令：expire 设置过期时间，单位秒
     *
     * @param key
     * @return
     */
    @Override
    public void expire(String key, long timeout) {
        redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * 实现命令：INCR key，增加key一次
     *
     * @param key
     * @return
     */
    @Override
    public long incr(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 实现命令：KEYS pattern，查找所有符合给定模式 pattern的 key
     */
    @Override
    public Set<String> keys(String pattern) {
        return redisTemplate.keys(pattern);
    }

    /**
     * 实现命令：DEL key，删除一个key
     *
     * @param key
     */
    @Override
    public void del(String key) {
        redisTemplate.delete(key);
    }

    // String（字符串）

    /**
     * 实现命令：SET key value，设置一个key-value（将字符串值 value关联到 key）
     *
     * @param key
     * @param value
     */
    @Override
    public void set(String key, String value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 实现命令：SET key value EX seconds，设置key-value和超时时间（秒）
     *
     * @param key
     * @param value
     * @param timeout （以秒为单位）
     */
    @Override
    public void set(String key, String value, long timeout) {
        redisTemplate.opsForValue().set(key, value, timeout, TimeUnit.SECONDS);
    }

    /**
     * 实现命令：GET key，返回 key所关联的字符串值。
     *
     * @param key
     * @return value
     */
    @Override
    public String get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 判断key是否存在
     *
     * @param key
     * @return value
     */
    @Override
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    public void batchDeleteKes(String pattern) {
        Set<String> keys = redisTemplate.keys(pattern);
        redisTemplate.delete(keys);
    }

}
